package com.xw.unification.utils.http.client;

import org.apache.http.config.ConnectionConfig;
import org.apache.http.config.RegistryBuilder;
import org.apache.http.config.SocketConfig;
import org.apache.http.conn.socket.ConnectionSocketFactory;
import org.apache.http.conn.socket.PlainConnectionSocketFactory;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.TrustSelfSignedStrategy;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
import org.apache.http.ssl.SSLContextBuilder;

import javax.net.ssl.SSLContext;
import java.nio.charset.StandardCharsets;

/**
 * @author qiwei
 */
public class HttpClientUtils {

    private static final PoolingHttpClientConnectionManager MANAGER;
    private static final SSLContext SSL_CONTEXT;
    private static final SSLConnectionSocketFactory SOCKET_FACTORY;

    private static final int TIMEOUT = 3600 * 10;

    static {
        ConnectionConfig connectionConfig = ConnectionConfig.custom()
                .setCharset(StandardCharsets.UTF_8)
                .build();
        SocketConfig socketConfig = SocketConfig.custom()
                .build();
        try {
            SSL_CONTEXT = new SSLContextBuilder().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build();
            SOCKET_FACTORY = new SSLConnectionSocketFactory(SSL_CONTEXT, NoopHostnameVerifier.INSTANCE);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.<ConnectionSocketFactory>create();
        registryBuilder.register("http", new PlainConnectionSocketFactory());
        registryBuilder.register("https", SOCKET_FACTORY);

        MANAGER = new PoolingHttpClientConnectionManager(registryBuilder.build());
        MANAGER.setDefaultConnectionConfig(connectionConfig);
        MANAGER.setDefaultSocketConfig(socketConfig);
        MANAGER.setDefaultMaxPerRoute(1000);
    }

    public static HttpBuilder http() {
        return new HttpBuilder(HttpClients.custom().setConnectionManager(MANAGER)
                .setSSLContext(SSL_CONTEXT)
                .setSSLSocketFactory(SOCKET_FACTORY));
    }

    public static HttpsBuilder https() {
        return new HttpsBuilder(HttpClients.custom().setConnectionManager(MANAGER)
                .setSSLContext(SSL_CONTEXT)
                .setSSLSocketFactory(SOCKET_FACTORY));
    }

    public static HttpBuilder http(PoolingHttpClientConnectionManager manager) {
        if (manager == null) {
            return http();
        }
        return new HttpBuilder(HttpClients.custom().setConnectionManager(manager));
    }

    public static HttpsBuilder https(PoolingHttpClientConnectionManager manager) {
        if (manager == null) {
            return https();
        }
        return new HttpsBuilder(HttpClients.custom().setConnectionManager(manager));
    }

}
